#!/bin/bash

# EMS生产环境部署脚本
# 用途: 部署EMS系统到生产环境，包含服务配置和系统集成

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

# 默认配置
INSTALL_DIR="/opt/ems"
SERVICE_USER="ems"
LOG_DIR="/var/log/ems"
CONFIG_DIR="/etc/ems"
SYSTEMD_SERVICE="ems-gateway.service"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查权限
check_permissions() {
    if [[ $EUID -ne 0 ]]; then
        log_error "此脚本需要root权限运行"
        log_info "请使用: sudo $0"
        exit 1
    fi
}

# 检查系统环境
check_system_environment() {
    log_info "检查生产环境..."
    
    # 检查操作系统
    if ! command -v systemctl &> /dev/null; then
        log_error "需要systemd支持的Linux系统"
        exit 1
    fi
    
    # 检查必要工具
    local tools=("curl" "tar" "gzip")
    for tool in "${tools[@]}"; do
        if ! command -v "$tool" &> /dev/null; then
            log_error "缺少必要工具: $tool"
            exit 1
        fi
    done
    
    log_success "系统环境检查完成"
}

# 创建服务用户
create_service_user() {
    log_info "创建服务用户..."
    
    if ! id "$SERVICE_USER" &>/dev/null; then
        useradd --system --home-dir "$INSTALL_DIR" --shell /bin/false "$SERVICE_USER"
        log_success "创建用户: $SERVICE_USER"
    else
        log_info "用户已存在: $SERVICE_USER"
    fi
}

# 创建目录结构
create_directory_structure() {
    log_info "创建目录结构..."
    
    # 创建安装目录
    mkdir -p "$INSTALL_DIR"/{bin,lib,web,logs}
    mkdir -p "$CONFIG_DIR"
    mkdir -p "$LOG_DIR"
    
    # 设置所有权
    chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
    chown -R "$SERVICE_USER:$SERVICE_USER" "$LOG_DIR"
    chown -R root:root "$CONFIG_DIR"
    chmod 755 "$CONFIG_DIR"
    
    log_success "目录结构创建完成"
}

# 部署应用文件
deploy_application() {
    log_info "部署应用文件..."
    
    # 检查构建产物
    if [ ! -f "$PROJECT_ROOT/build/ems-cpp-v1" ]; then
        log_error "未找到可执行文件，请先运行构建"
        log_info "运行: $PROJECT_ROOT/scripts/build.sh"
        exit 1
    fi
    
    # 复制可执行文件
    cp "$PROJECT_ROOT/build/ems-cpp-v1" "$INSTALL_DIR/bin/"
    chmod +x "$INSTALL_DIR/bin/ems-cpp-v1"
    
    # 复制Web文件
    if [ -d "$PROJECT_ROOT/build/web" ]; then
        cp -r "$PROJECT_ROOT/build/web/"* "$INSTALL_DIR/web/"
        log_info "Web文件已部署"
    else
        log_warning "未找到Web构建产物"
    fi
    
    # 复制配置文件
    if [ -d "$PROJECT_ROOT/config" ]; then
        cp -r "$PROJECT_ROOT/config/"* "$CONFIG_DIR/"
        # 更新配置文件中的路径
        sed -i "s|./logs/|$LOG_DIR/|g" "$CONFIG_DIR/system.json" 2>/dev/null || true
        log_info "配置文件已部署"
    fi
    
    # 设置权限
    chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_DIR"
    chmod 755 "$INSTALL_DIR/bin/ems-cpp-v1"
    
    log_success "应用文件部署完成"
}

# 创建systemd服务
create_systemd_service() {
    log_info "创建systemd服务..."
    
    cat > "/etc/systemd/system/$SYSTEMD_SERVICE" << EOF
[Unit]
Description=EMS Energy Management System Gateway
Documentation=https://github.com/your-org/ems-cpp-v1
After=network.target
Wants=network.target

[Service]
Type=simple
User=$SERVICE_USER
Group=$SERVICE_USER
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/bin/ems-cpp-v1 --config=$CONFIG_DIR
ExecReload=/bin/kill -HUP \$MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
Restart=always
RestartSec=10

# 安全设置
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=$LOG_DIR $CONFIG_DIR
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true

# 资源限制
LimitNOFILE=65536
LimitNPROC=4096

# 环境变量
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Environment=EMS_CONFIG_DIR=$CONFIG_DIR
Environment=EMS_LOG_DIR=$LOG_DIR
Environment=EMS_DATA_DIR=$INSTALL_DIR

[Install]
WantedBy=multi-user.target
EOF
    
    # 重载systemd配置
    systemctl daemon-reload
    
    log_success "systemd服务已创建"
}

# 配置防火墙
configure_firewall() {
    log_info "配置防火墙..."
    
    # 检查防火墙工具
    if command -v ufw &> /dev/null; then
        # Ubuntu/Debian UFW
        ufw allow 8080/tcp comment "EMS Web Interface"
        ufw allow 8081/tcp comment "EMS API"
        ufw allow 8082/tcp comment "EMS WebSocket"
        log_info "UFW规则已添加"
    elif command -v firewall-cmd &> /dev/null; then
        # CentOS/RHEL firewalld
        firewall-cmd --permanent --add-port=8080/tcp
        firewall-cmd --permanent --add-port=8081/tcp
        firewall-cmd --permanent --add-port=8082/tcp
        firewall-cmd --reload
        log_info "firewalld规则已添加"
    else
        log_warning "未检测到防火墙工具，请手动配置端口: 8080,8081,8082"
    fi
}

# 配置日志轮转
configure_log_rotation() {
    log_info "配置日志轮转..."
    
    cat > "/etc/logrotate.d/ems" << EOF
$LOG_DIR/*.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 644 $SERVICE_USER $SERVICE_USER
    postrotate
        systemctl reload-or-restart $SYSTEMD_SERVICE > /dev/null 2>&1 || true
    endscript
}
EOF
    
    log_success "日志轮转配置完成"
}

# 启用并启动服务
start_service() {
    log_info "启动EMS服务..."
    
    # 启用自动启动
    systemctl enable "$SYSTEMD_SERVICE"
    
    # 启动服务
    systemctl start "$SYSTEMD_SERVICE"
    
    # 检查状态
    sleep 3
    if systemctl is-active --quiet "$SYSTEMD_SERVICE"; then
        log_success "EMS服务启动成功"
    else
        log_error "EMS服务启动失败"
        systemctl status "$SYSTEMD_SERVICE"
        exit 1
    fi
}

# 验证部署
verify_deployment() {
    log_info "验证部署..."
    
    # 检查服务状态
    if ! systemctl is-active --quiet "$SYSTEMD_SERVICE"; then
        log_error "服务未运行"
        return 1
    fi
    
    # 检查端口监听
    local ports=(8080 8081 8082)
    for port in "${ports[@]}"; do
        if ss -tuln | grep -q ":$port "; then
            log_success "端口 $port 正在监听"
        else
            log_warning "端口 $port 未监听"
        fi
    done
    
    # 测试HTTP连接
    if curl -s -o /dev/null -w "%{http_code}" "http://localhost:8080" | grep -q "200\|302"; then
        log_success "Web界面可访问"
    else
        log_warning "Web界面访问异常"
    fi
    
    log_success "部署验证完成"
}

# 显示部署信息
show_deployment_info() {
    log_success "EMS生产环境部署完成！"
    echo
    log_info "系统信息:"
    log_info "  安装目录: $INSTALL_DIR"
    log_info "  配置目录: $CONFIG_DIR"
    log_info "  日志目录: $LOG_DIR"
    log_info "  服务用户: $SERVICE_USER"
    echo
    log_info "服务管理:"
    log_info "  启动服务: systemctl start $SYSTEMD_SERVICE"
    log_info "  停止服务: systemctl stop $SYSTEMD_SERVICE"
    log_info "  重启服务: systemctl restart $SYSTEMD_SERVICE"
    log_info "  查看状态: systemctl status $SYSTEMD_SERVICE"
    log_info "  查看日志: journalctl -u $SYSTEMD_SERVICE -f"
    echo
    log_info "访问地址:"
    log_info "  Web管理界面: http://$(hostname -I | awk '{print $1}'):8080"
    log_info "  API接口: http://$(hostname -I | awk '{print $1}'):8081"
    echo
    log_info "重要文件:"
    log_info "  主配置: $CONFIG_DIR/system.json"
    log_info "  MQTT配置: $CONFIG_DIR/mqtt.json"
    log_info "  设备配置: $CONFIG_DIR/devices.json"
    echo
    log_warning "请检查并更新配置文件后重启服务"
}

# 卸载函数
uninstall() {
    log_info "卸载EMS系统..."
    
    # 停止并禁用服务
    systemctl stop "$SYSTEMD_SERVICE" 2>/dev/null || true
    systemctl disable "$SYSTEMD_SERVICE" 2>/dev/null || true
    
    # 删除服务文件
    rm -f "/etc/systemd/system/$SYSTEMD_SERVICE"
    systemctl daemon-reload
    
    # 删除文件
    rm -rf "$INSTALL_DIR"
    rm -rf "$CONFIG_DIR"
    rm -f "/etc/logrotate.d/ems"
    
    # 删除用户
    userdel "$SERVICE_USER" 2>/dev/null || true
    
    # 删除日志 (可选)
    if [ "$REMOVE_LOGS" = "true" ]; then
        rm -rf "$LOG_DIR"
    fi
    
    log_success "卸载完成"
}

# 主函数
main() {
    log_info "开始部署EMS生产环境..."
    
    check_permissions
    check_system_environment
    create_service_user
    create_directory_structure
    deploy_application
    create_systemd_service
    configure_firewall
    configure_log_rotation
    start_service
    verify_deployment
    show_deployment_info
}

# 处理命令行参数
while [[ $# -gt 0 ]]; do
    case $1 in
        --install-dir)
            INSTALL_DIR="$2"
            shift 2
            ;;
        --service-user)
            SERVICE_USER="$2"
            shift 2
            ;;
        --uninstall)
            uninstall
            exit 0
            ;;
        --remove-logs)
            REMOVE_LOGS=true
            shift
            ;;
        --help|-h)
            echo "用法: $0 [选项]"
            echo "选项:"
            echo "  --install-dir DIR    安装目录 (默认: $INSTALL_DIR)"
            echo "  --service-user USER  服务用户 (默认: $SERVICE_USER)"
            echo "  --uninstall          卸载系统"
            echo "  --remove-logs        卸载时删除日志"
            echo "  --help, -h           显示此帮助信息"
            exit 0
            ;;
        *)
            log_error "未知选项: $1"
            exit 1
            ;;
    esac
done

main